package main;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

// Nikolas Wolfe
// 3/18/09
// CIS 4930
// Game Of Life

// This has the title / menu bar functionality

public class FrameOfLife extends JFrame
{
	private final PaneOfLife paneOfLife;
	private GameOfLife gameOfLife;
	private DialogBox numGensDialog;
	private DialogBox numThreadsDialog;
	private final String title = "CIS 4930: C & P Programming, " +
	"2009S - Program 3 - Nikolas Wolfe";
	
	public FrameOfLife( PaneOfLife panel )
	{
		this.paneOfLife = panel;
		this.setTitle( title );
	}
	
	//=========================================================================
	// inititialize()
	
	public void initialize()
	{
		attachMenuBar();
		this.numGensDialog = new DialogBox( 0, "Generations", this );
		this.numThreadsDialog = new DialogBox( 1, "Threads", this );
		numGensDialog.initialize();
		numThreadsDialog.initialize();
		this.gameOfLife = new GameOfLife(this);
		this.getContentPane().add( paneOfLife, BorderLayout.CENTER );
		this.getContentPane().add( makeGenerationsButton(), BorderLayout.SOUTH );
	}
	
	//=========================================================================
	// attachMenuBar()
	
	private void attachMenuBar()
	{
		JMenuItem item;
		JMenu menu;
		JMenuBar menuBar = new JMenuBar();
		
		// ====== File Menu ======
		menu = new JMenu( "File" );
		
		// Load Config...
		item = new JMenuItem( "Load Configuration..." );
		item.addActionListener( new ActionListener()
		{
			public void actionPerformed( ActionEvent event )
			{
				// do shit
			}
		});
		menu.add( item );
		
		// Save Config...
		item = new JMenuItem( "Save Configuration..." );
		item.addActionListener( new ActionListener()
		{
			public void actionPerformed( ActionEvent event )
			{
				// do shit
			}
		});
		menu.add( item );
		
		// Save Image
		item = new JMenuItem( "Save Image..." );
		item.addActionListener( new ActionListener()
		{
			public void actionPerformed( ActionEvent event )
			{
				// do shit
			}
		});
		menu.add( item );
		
		// Exit
		item = new JMenuItem( "Exit" );
		item.addActionListener( new ActionListener()
		{
			public void actionPerformed( ActionEvent event )
			{
				System.exit( 0 );
			}
		});
		menu.add( item );
		
		// attach menu to menu bar
		menuBar.add( menu );
		
		// ====== Concurrency Menu ======
		menu = new JMenu( "Concurrency" );
		
		// # Threads
		item = new JMenuItem( "# Threads" );
		item.addActionListener( new ActionListener()
		{
			public void actionPerformed( ActionEvent event )
			{
				numThreadsDialog.show();
			}
		});
		menu.add( item );
		
		// # Generations
		item = new JMenuItem( "# Generations" );
		item.addActionListener( new ActionListener()
		{
			public void actionPerformed( ActionEvent event )
			{
				numGensDialog.show();
			}
		});
		menu.add( item );
		
		// attach menu to menu bar
		menuBar.add( menu );
		
		// set menu bar
		this.setJMenuBar( menuBar );
	}
	
	//=========================================================================
	// makeGenerationsButton()		
	
	private JButton makeGenerationsButton()
	{
		// initialize in Paused State
		final JButton generationsButton = new JButton("Paused: Press to run");
		generationsButton.addActionListener( new ActionListener()
		{
			private ButtonState pausedState = new PausedState();
			private ButtonState runningState = new RunningState();
			private ButtonState currentState = pausedState;
			
			public void actionPerformed(ActionEvent event)
			{
				currentState.actionPerformed(event);
			}
			
			abstract class ButtonState implements ActionListener
			{
				public abstract void actionPerformed(ActionEvent event);
				public abstract void setAsState();
			}
			
			class PausedState extends ButtonState
			{	
				@Override
				public void actionPerformed(ActionEvent event)
				{
					// get the board ready
					gameOfLife.initialize();
					runningState.setAsState();
				}
				@Override
				public void setAsState()
				{
					currentState = this;
					paneOfLife.resumePane(); // enable mouse movement
					int n = getNumGenerations();
					if( n > 0) {
						generationsButton.setText("Paused: press to run for " + 
								n + " generations" );
					}
					else {
						generationsButton.setText("Paused: Press to run");
					}
					
					// stop the game!
					gameOfLife.stop();
				}
			}
			class RunningState extends ButtonState
			{
				@Override
				public void actionPerformed(ActionEvent event)
				{
					pausedState.setAsState();
				}
				@Override
				public void setAsState()
				{
					currentState = this;
					paneOfLife.pausePane(); // disable mouse movement	
					int n = getNumGenerations();
					if( n > 0) {
						generationsButton.setText("Running for " + n + 
								" generations: please wait..." );
					}
					else {
						generationsButton.setText("Running: Press to pause");
					}
					
					// start the game!
					gameOfLife.start();
				}
			}
		});
		return generationsButton;
	}
	
	//=========================================================================
	// # Generations / Threads mutator
	
	public int getNumGenerations()
	{
		return numGensDialog.getVal();
	}
	
	//=========================================================================
	// # Threads mutator
	
	public int getNumThreads()
	{
		return numThreadsDialog.getVal();
	}

	//=========================================================================
	// getPaneOfLife() get the panel
	
	public PaneOfLife getPaneOfLife()
	{
		return paneOfLife;
	}
}
